package com.flyco.roundview;

import static ohos.agp.components.ComponentState.COMPONENT_STATE_PRESSED;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.agp.utils.Color;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;

public class RoundViewDelegate implements Component.ComponentStateChangedListener {

    private Component view;

    private Context context;

    private ShapeElement gd_background = new ShapeElement();

    private ShapeElement gd_background_press = new ShapeElement();

    private int backgroundColor;

    private int backgroundPressColor;

    private int cornerRadius;

    private int cornerRadius_TL;

    private int cornerRadius_TR;

    private int cornerRadius_BL;

    private int cornerRadius_BR;

    private int strokeWidth;

    private int strokeColor;

    private int strokePressColor;

    private int textPressColor;

    private boolean isRadiusHalfHeight;

    private boolean isWidthHeightEqual;

    private float[] radiusArr = new float[8];

    private int[] colorList;

    private static final String ROUNDTEXTVIEW_RV_BACKGROUNDCOLOR = "rv_backgroundColor";

    private static final String ROUNDTEXTVIEW_RV_BACKGROUNDPRESSCOLOR = "rv_backgroundPressColor";

    private static final String ROUNDTEXTVIEW_RV_STROKECOLOR = "rv_strokeColor";

    private static final String ROUNDTEXTVIEW_RV_STROKEPRESSCOLOR = "rv_strokePressColor";

    private static final String ROUNDTEXTVIEW_TEXTPRESSCOLOR = "rv_textPressColor";

    private static final String ROUNDTEXTVIEW_RV_ISRADIUSHALFHEIGHT = "rv_isRadiusHalfHeight";

    private static final String ROUNDTEXTVIEW_RV_ISWIDTHHEIGHTEQUAL = "rv_isWidthHeightEqual";

    private static final String ROUNDTEXTVIEW_RV_ISRIPPLEENABLE = "rv_isRippleEnable";

    private static final String ROUNDTEXTVIEW_RV_CORNERRADIUS = "rv_cornerRadius";

    private static final String ROUNDTEXTVIEW_RV_STROKEWIDTH = "rv_strokeWidth";

    private static final String ROUNDTEXTVIEW_RV_CORNERRADIUS_TL = "rv_cornerRadius_TL";

    private static final String ROUNDTEXTVIEW_RV_CORNERRADIUS_TR = "rv_cornerRadius_TR";

    private static final String ROUNDTEXTVIEW_RV_CORNERRADIUS_BL = "rv_cornerRadius_BL";

    private static final String ROUNDTEXTVIEW_RV_CORNERRADIUS_BR = "rv_cornerRadius_BR";

    private static final int COLOR_TRANSPARENT = 0;

    private static final int DEFAULT_DIMENSION = 0;

    private static final int COMPONENT_STATE = 18432; //Constant or Field name not available in Component class

    private static final int PRESSED_STATE = 1;

    private static final int UNPRESSED_STATE = 0;

    public RoundViewDelegate(Component view, Context context, AttrSet attrs) {
        this.view = view;
        this.context = context;
        obtainAttributes(context, attrs);
        view.setComponentStateChangedListener(this::onComponentStateChanged);
    }

    private void obtainAttributes(Context context, AttrSet attrs) {
        backgroundColor = attrs.getAttr(ROUNDTEXTVIEW_RV_BACKGROUNDCOLOR).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_BACKGROUNDCOLOR).get().getColorValue().getValue() : COLOR_TRANSPARENT;
        backgroundPressColor = attrs.getAttr(ROUNDTEXTVIEW_RV_BACKGROUNDPRESSCOLOR).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_BACKGROUNDPRESSCOLOR).get().getColorValue().getValue() : COLOR_TRANSPARENT;
        cornerRadius = attrs.getAttr(ROUNDTEXTVIEW_RV_CORNERRADIUS).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_CORNERRADIUS).get().getDimensionValue() : DEFAULT_DIMENSION;
        strokeWidth = attrs.getAttr(ROUNDTEXTVIEW_RV_STROKEWIDTH).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_STROKEWIDTH).get().getDimensionValue() : DEFAULT_DIMENSION;
        strokeColor = attrs.getAttr(ROUNDTEXTVIEW_RV_STROKECOLOR).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_STROKECOLOR).get().getColorValue().getValue() : COLOR_TRANSPARENT;
        strokePressColor = attrs.getAttr(ROUNDTEXTVIEW_RV_STROKEPRESSCOLOR).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_STROKEPRESSCOLOR).get().getColorValue().getValue() : Integer.MAX_VALUE;
        textPressColor = attrs.getAttr(ROUNDTEXTVIEW_TEXTPRESSCOLOR).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_TEXTPRESSCOLOR).get().getColorValue().getValue() : Integer.MAX_VALUE;
        isRadiusHalfHeight = attrs.getAttr(ROUNDTEXTVIEW_RV_ISRADIUSHALFHEIGHT).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_ISRADIUSHALFHEIGHT).get().getBoolValue() : false;
        isWidthHeightEqual = attrs.getAttr(ROUNDTEXTVIEW_RV_ISWIDTHHEIGHTEQUAL).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_ISWIDTHHEIGHTEQUAL).get().getBoolValue() : false;
        cornerRadius_TL = attrs.getAttr(ROUNDTEXTVIEW_RV_CORNERRADIUS_TL).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_CORNERRADIUS_TL).get().getDimensionValue() : DEFAULT_DIMENSION;
        cornerRadius_TR = attrs.getAttr(ROUNDTEXTVIEW_RV_CORNERRADIUS_TR).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_CORNERRADIUS_TR).get().getDimensionValue() : DEFAULT_DIMENSION;
        cornerRadius_BL = attrs.getAttr(ROUNDTEXTVIEW_RV_CORNERRADIUS_BL).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_CORNERRADIUS_BL).get().getDimensionValue() : DEFAULT_DIMENSION;
        cornerRadius_BR = attrs.getAttr(ROUNDTEXTVIEW_RV_CORNERRADIUS_BR).isPresent() ? attrs.getAttr(
            ROUNDTEXTVIEW_RV_CORNERRADIUS_BR).get().getDimensionValue() : DEFAULT_DIMENSION;
    }

    public void setBackgroundColor(int backgroundColor) {
        this.backgroundColor = backgroundColor;
        setBgSelector();
    }

    public void setBackgroundPressColor(int backgroundPressColor) {
        this.backgroundPressColor = backgroundPressColor;
        setBgSelector();
    }

    public void setCornerRadius(int cornerRadius) {
        this.cornerRadius = dp2px(cornerRadius);
        setBgSelector();
    }

    public void setStrokeWidth(int strokeWidth) {
        this.strokeWidth = dp2px(strokeWidth);
        setBgSelector();
    }

    public void setStrokeColor(int strokeColor) {
        this.strokeColor = strokeColor;
        setBgSelector();
    }

    public void setStrokePressColor(int strokePressColor) {
        this.strokePressColor = strokePressColor;
        setBgSelector();
    }

    public void setTextPressColor(int textPressColor) {
        this.textPressColor = textPressColor;
        setBgSelector();
    }

    public void setIsRadiusHalfHeight(boolean isRadiusHalfHeight) {
        this.isRadiusHalfHeight = isRadiusHalfHeight;
        setBgSelector();
    }

    public void setIsWidthHeightEqual(boolean isWidthHeightEqual) {
        this.isWidthHeightEqual = isWidthHeightEqual;
        setBgSelector();
    }

    public void setCornerRadius_TL(int cornerRadius_TL) {
        this.cornerRadius_TL = cornerRadius_TL;
        setBgSelector();
    }

    public void setCornerRadius_TR(int cornerRadius_TR) {
        this.cornerRadius_TR = cornerRadius_TR;
        setBgSelector();
    }

    public void setCornerRadius_BL(int cornerRadius_BL) {
        this.cornerRadius_BL = cornerRadius_BL;
        setBgSelector();
    }

    public void setCornerRadius_BR(int cornerRadius_BR) {
        this.cornerRadius_BR = cornerRadius_BR;
        setBgSelector();
    }

    public int getBackgroundColor() {
        return backgroundColor;
    }

    public int getBackgroundPressColor() {
        return backgroundPressColor;
    }

    public int getCornerRadius() {
        return cornerRadius;
    }

    public int getStrokeWidth() {
        return strokeWidth;
    }

    public int getStrokeColor() {
        return strokeColor;
    }

    public int getStrokePressColor() {
        return strokePressColor;
    }

    public int getTextPressColor() {
        return textPressColor;
    }

    public boolean isRadiusHalfHeight() {
        return isRadiusHalfHeight;
    }

    public boolean isWidthHeightEqual() {
        return isWidthHeightEqual;
    }

    public int getCornerRadius_TL() {
        return cornerRadius_TL;
    }

    public int getCornerRadius_TR() {
        return cornerRadius_TR;
    }

    public int getCornerRadius_BL() {
        return cornerRadius_BL;
    }

    public int getCornerRadius_BR() {
        return cornerRadius_BR;
    }

    protected int dp2px(float dp) {
        final float scale = DisplayManager.getInstance().getDefaultDisplay(context).get().getAttributes().densityPixels;
        return (int) (dp * scale + 0.5f);
    }

    private void setDrawable(ShapeElement gd, int color, int strokeColor) {
        gd.setRgbColor(RgbColor.fromArgbInt(color));
        if (cornerRadius_TL > 0 || cornerRadius_TR > 0 || cornerRadius_BR > 0 || cornerRadius_BL > 0) {
            /**The corners are ordered top-left, top-right, bottom-right, bottom-left*/
            radiusArr[0] = cornerRadius_TL;
            radiusArr[1] = cornerRadius_TL;
            radiusArr[2] = cornerRadius_TR;
            radiusArr[3] = cornerRadius_TR;
            radiusArr[4] = cornerRadius_BR;
            radiusArr[5] = cornerRadius_BR;
            radiusArr[6] = cornerRadius_BL;
            radiusArr[7] = cornerRadius_BL;
            gd.setCornerRadiiArray(radiusArr);
        } else {
            gd.setCornerRadius(cornerRadius);
        }
        gd.setStroke(strokeWidth, RgbColor.fromArgbInt(strokeColor));
    }

    public void setBgSelector() {
        StateElement bg = new StateElement();

        // RippleDrawable Not Available in HMO
        /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && isRippleEnable) {
            setDrawable(gd_background, backgroundColor, strokeColor);
            RippleDrawable rippleDrawable = new RippleDrawable(
                getPressedColorSelector(backgroundColor, backgroundPressColor), gd_background, null);
            view.setBackground(rippleDrawable);
        } else {*/
        setDrawable(gd_background, backgroundColor, strokeColor);
        bg.addState(new int[] {-COMPONENT_STATE_PRESSED}, gd_background);
        if (backgroundPressColor != Integer.MAX_VALUE || strokePressColor != Integer.MAX_VALUE) {
            setDrawable(gd_background_press,
                backgroundPressColor == Integer.MAX_VALUE ? backgroundColor : backgroundPressColor,
                strokePressColor == Integer.MAX_VALUE ? strokeColor : strokePressColor);
            bg.addState(new int[] {COMPONENT_STATE_PRESSED}, gd_background_press);
        }

        view.setBackground(bg);

        if (view instanceof Text) {
            if (textPressColor != Integer.MAX_VALUE) {
                Color textColors = ((Text) view).getTextColor();
                colorList = new int[] {textColors.getValue(), textPressColor};
            }
        }

    }

    @Override
    public void onComponentStateChanged(Component component, int state) {
        switch (state) {
            case COMPONENT_STATE:
                if(colorList!=null)
                ((Text) view).setTextColor(new Color(colorList[PRESSED_STATE]));
                break;
            default:
                if(colorList!=null)
                ((Text) view).setTextColor(new Color(colorList[UNPRESSED_STATE]));
                break;
        }
    }
}
